---
title: GitHub Actions
id: github-actions
slug: /integrations/github-actions
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

[GitHub Actions](https://github.com/features/actions) is a popular CI/CD 
product from GitHub. With GitHub Actions, users can easily define workflows
that are triggered in various lifecycle events related to a Git repository.
For example, many teams configure GitHub actions to run all unit tests in
a repository on each change that is committed to a repository. 

One of the powerful features of GitHub Actions is its extensibility: it is
very easy to package a piece of functionality as a module (called an "action")
that can later be re-used by many projects. 

## CI for database schema changes

Teams using GitHub that wish to ensure all changes to their database schema are safe
can use the [`atlas-action`](https://github.com/ariga/atlas-action) GitHub Action.

This action is used for [linting migration directories](/versioned/lint)
using the `atlas migrate lint` command. This command  validates and analyzes the contents
of migration directories and generates insights and diagnostics on the selected changes:

* Ensure the migration history can be replayed from any point at time.
* Protect from unexpected history changes when concurrent migrations are written to the migration directory by
  multiple team members. Read more about the consistency checks in the section below.
* Detect whether destructive or irreversible changes have been made or whether they are dependent on tables'  
  contents and can cause a migration failure.

### Supported directory formats

This action supports analyzing migration directories in formats
accepted by different schema migration tools:
* [Atlas](https://atlasgo.io)
* [golang-migrate](https://github.com/golang-migrate/migrate)
* [goose](https://github.com/pressly/goose)
* [dbmate](https://github.com/amacneil/dbmate)
* [Liquibase](https://liquibase.org)
* [Flyway](https://flywaydb.org)

### Usage

Add `.github/workflows/atlas-ci.yaml` to your repo with the following contents:
<Tabs
defaultValue="mysql"
values={[
    {label: 'MySQL', value: 'mysql'},
    {label: 'MariaDB', value: 'maria'},
    {label: 'PostgreSQL', value: 'postgres'},
]}>
<TabItem value="mysql">

```yaml
name: Atlas CI
on:
  # Run whenever code is changed in the master branch,
  # change this to your root branch.
  push:
    branches:
      - master
  # Run on PRs where something changed under the `path/to/migration/dir/` directory.
  pull_request:
    paths:
      - 'path/to/migration/dir/*'
jobs:
  lint:
    services:
      # Spin up a mysql:8.0.29 container to be used as the dev-database for analysis.
      mysql:
        image: mysql:8.0.29
        env:
          MYSQL_ROOT_PASSWORD: pass
          MYSQL_DATABASE: test
        ports:
          - "3307:3306"
        options: >-
          --health-cmd "mysqladmin ping -ppass"
          --health-interval 10s
          --health-start-period 10s
          --health-timeout 5s
          --health-retries 10
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.1
        with:
          fetch-depth: 0 # Mandatory unless "latest" is set below.
      - uses: ariga/atlas-action@v0
        with:
          dir: path/to/migrations
          dir-format: atlas # Or: golang-migrate, liquibase, flyway, goose, dbmate
          dev-url: mysql://root:pass@localhost:3307/test
```

</TabItem>
<TabItem value="maria">

```yaml
name: Atlas CI
on:
  # Run whenever code is changed in the master branch,
  # change this to your root branch.
  push:
    branches:
      - master
  # Run on PRs where something changed under the `path/to/migration/dir/` directory.
  pull_request:
    paths:
      - 'path/to/migration/dir/*'
jobs:
  lint:
    services:
      # Spin up a maria:10.7 container to be used as the dev-database for analysis.
      maria107:
        image: mariadb:10.7
        env:
          MYSQL_DATABASE: test
          MYSQL_ROOT_PASSWORD: pass
        ports:
          - 4306:3306
        options: >-
          --health-cmd "mysqladmin ping -ppass"
          --health-interval 10s
          --health-start-period 10s
          --health-timeout 5s
          --health-retries 10
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.1
        with:
          fetch-depth: 0 # Mandatory unless "latest" is set below.
      - uses: ariga/atlas-action@v0
        with:
          dir: path/to/migrations
          dir-format: atlas # Or: golang-migrate, liquibase, flyway, goose, dbmate
          dev-url: maria://root:pass@localhost:4306/test
```

</TabItem>
<TabItem value="postgres">

```yaml
name: Atlas CI
on:
  # Run whenever code is changed in the master branch,
  # change this to your root branch.
  push:
    branches:
      - master
  # Run on PRs where something changed under the `path/to/migration/dir/` directory.
  pull_request:
    paths:
      - 'path/to/migration/dir/*'
jobs:
  lint:
    services:
      # Spin up a postgres:10 container to be used as the dev-database for analysis.
      postgres10:
        image: postgres:10
        env:
          POSTGRES_DB: test
          POSTGRES_PASSWORD: pass
        ports:
          - 5430:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.1
        with:
          fetch-depth: 0 # Mandatory unless "latest" is set below.
      - uses: ariga/atlas-action@v0
        with:
          dir: path/to/migrations
          dir-format: atlas # Or: golang-migrate, liquibase, flyway, goose, dbmate
          dev-url: postgres://postgres:pass@localhost:5430/test?sslmode=disable
```

</TabItem>
</Tabs>

### Configuration

Configure the action by passing input parameters in the `with:` block.

#### `dir`

Sets the directory that contains the migration scripts to analyze.

#### `dir-format`

Sets the format of the migration directory. Options: `atlas` (default),
`golang-migrate`, `goose` or `dbmate`, `flyway`, `liquibase`.

#### `dev-url`

The URL of the dev-database to use for analysis.

* Read about [Atlas URL formats](/concepts/url)
* Read about [dev-databases](/concepts/dev-database)

#### `latest`

Use the `latest` mode to decide which files to analyze. By default,
Atlas will use `git-base` to analyze any files that are present in the
diff between the base branch and the current.

Unless this option is set, the base branch (`master`/`main`/etc) must
be checked out locally or you will see an error such as:
```
Atlas failed with code 1: Error: git diff: exit status 128
```

The full list of input options can be found in [action.yml](https://github.com/ariga/atlas-action/blob/master/action.yml).